
const target = new WeakMap();

class EventEmiter {
    constructor() {
        target.set(this, {
            events: []
        })
    }
    on(type, fn) {
        const events = target.get(this).events;
        if(events.findIndex(e => e.type === type && e.fn === fn) > -1) return;
        events.unshift({
            type, fn
        })
    }
    emit(type, ...args) {
        const events = target.get(this).events;
        for(let i = events.length - 1; i > -1; i--) {
            if(events[i].type === type) {
                events[i].fn(...args);
            }
        }
    }
    off(type, fn) {
        const events = target.get(this).events;
        const hasFn = typeof fn === 'function';
        for(let i = 0, l = events.length; i < l; i++) {
            if(hasFn) {
                if(events[i].type === type && events[i].fn === fn) {
                    events.splice(i, 1);
                    break;
                }
            } else {
                if(events[i].type === type) {
                    events.splice(i, 1);
                }
            }
        }
    }
    once(type, fn) {
        const _once = () => {
            fn();
            this.off(type, _once);
        };
        this.on(type, _once);
    }
    destroy() {
        target.get(this).events = null;
        target.delete(this);
    }
}

export default EventEmiter